﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Xml.Linq;
using RPGXEngine;

namespace RPGX.Graphics
{
    public abstract class HUDObject
    {
        #region Properties

        public HUD HUD
        {
            get { return _hud; }
            set { _hud = value; }
        }
        private HUD _hud = null;

        public HUDObject Parent
        {
            get { return _parent; }
            set { _parent = value; }
        }
        private HUDObject _parent = null;

        public List<HUDObject> ChildObjects
        {
            get
            {
                return this._childObjects;
            }
            set
            {
                this._childObjects = value;
            }
        }
        private List<HUDObject> _childObjects = new List<HUDObject>();

        public Vector2 PositionRelativeToParent
        {
            get
            {
                return this._positionRelativeToParent;
            }
            set
            {
                this._positionRelativeToParent = value;
            }
        }
        private Vector2 _positionRelativeToParent = new Vector2();

        public int Width
        {
            get
            {
                if (this._widthAsPercentageOfParent > -1)
                {
                    int w = this.Parent == null ? this.HUD.Width : this.Parent.Width;
                    return (int)(((float)w / 100.0f) * (float)this._widthAsPercentageOfParent);
                }
                else
                {
                    return this._width;
                }
            }
            set { _width = value; }
        }
        private int _width = 0;

        public int Height
        {
            get
            {
                if (this._heightAsPercentageOfParent > -1)
                {
                    int h = this.Parent == null ? this.HUD.Height : this.Parent.Height;
                    return (int)(((float)h / 100.0f) * (float)this._heightAsPercentageOfParent);
                }
                else
                {
                    return this._height;
                }
            }
            set { _height = value; }
        }
        private int _height = 0;

        public int WidthAsPercentageOfParent
        {
            get { return _widthAsPercentageOfParent; }
            set { _widthAsPercentageOfParent = value; }
        }
        private int _widthAsPercentageOfParent = -1;

        public int HeightAsPercentageOfParent
        {
            get { return _heightAsPercentageOfParent; }
            set { _heightAsPercentageOfParent = value; }
        }
        private int _heightAsPercentageOfParent = -1;

        public string Id
        {
            get
            {
                return this._id;
            }
            set
            {
                this._id = value;
            }
        }
        private string _id = String.Empty;

        public string MouseType
        {
            get { return _mouseType; }
            set { _mouseType = value; }
        }
        private string _mouseType = String.Empty;

        public bool IsFocused
        {
            get { return _isFocused; }
            set { _isFocused = value; }
        }
        private bool _isFocused = false;

        public abstract string Name
        {
            get;
        }

        public string OnMouseOverScriptAction
        {
            get { return _onMouseOverScriptAction; }
            set { _onMouseOverScriptAction = value; }
        }
        private string _onMouseOverScriptAction = String.Empty;

        public string OnMouseEnterScriptAction
        {
            get { return _onMouseEnterScriptAction; }
            set { _onMouseEnterScriptAction = value; }
        }
        private string _onMouseEnterScriptAction = String.Empty;

        public string OnMouseLeaveScriptAction
        {
            get { return _onMouseLeaveScriptAction; }
            set { _onMouseLeaveScriptAction = value; }
        }
        private string _onMouseLeaveScriptAction = String.Empty;

        public string OnMouseClickScriptAction
        {
            get { return _onMouseClickScriptAction; }
            set { _onMouseClickScriptAction = value; }
        }
        private string _onMouseClickScriptAction = String.Empty;

        public string OnMouseDownScriptAction
        {
            get { return _onMouseDownScriptAction; }
            set { _onMouseDownScriptAction = value; }
        }
        private string _onMouseDownScriptAction = String.Empty;

        public string OnMouseUpScriptAction
        {
            get { return _onMouseUpScriptAction; }
            set { _onMouseUpScriptAction = value; }
        }
        private string _onMouseUpScriptAction = String.Empty;

        public string OnFocusInScriptAction
        {
            get { return _onFocusInScriptAction; }
            set { _onFocusInScriptAction = value; }
        }
        private string _onFocusInScriptAction = String.Empty;

        public string OnFocusOutScriptAction
        {
            get { return _onFocusOutScriptAction; }
            set { _onFocusOutScriptAction = value; }
        }
        private string _onFocusOutScriptAction = String.Empty;

        #endregion

        #region Public Methods

        public abstract bool Render(GameTime time, SpriteBatch spriteBatch, Rectangle bounds);

        public abstract bool FromXML(XElement element, HUD hud);

        public abstract bool UnLoad();

        public virtual void Update(GameTime time)
        {
            if (this.ChildObjects != null)
            {
                foreach (var o in this.ChildObjects)
                {
                    o.Update(time);
                }
            }
        }

        #region Events

        public virtual void OnMouseOver(HUDMouseOverEventArgs e)
        {
            this.HUD.Script.RunCode(this.OnMouseOverScriptAction);
        }

        public virtual void OnMouseEnter(HUDMouseEnterEventArgs e)
        {
            this.HUD.Script.RunCode(this.OnMouseEnterScriptAction);
        }

        public virtual void OnMouseLeave(HUDMouseLeaveEventArgs e)
        {
            this.HUD.Script.RunCode(this.OnMouseLeaveScriptAction);
        }

        public virtual void OnMouseClick(HUDMouseClickEventArgs e)
        {
            this.HUD.Script.RunCode(this.OnMouseClickScriptAction);
        }

        public virtual void OnMouseDown(HUDMouseDownEventArgs e)
        {
            this.HUD.Script.RunCode(this.OnMouseDownScriptAction);
        }

        public virtual void OnMouseUp(HUDMouseUpEventArgs e)
        {
            this.HUD.Script.RunCode(this.OnMouseUpScriptAction);
        }

        public virtual void OnFocusIn(HUDFocusInEventArgs e)
        {
            this.HUD.Script.RunCode(this.OnFocusInScriptAction);
        }

        public virtual void OnFocusOut(HUDFocusOutEventArgs e)
        {
            this.HUD.Script.RunCode(this.OnFocusOutScriptAction);
        }

        public virtual void OnKeyDown(HUDKeyDownEventArgs e)
        {
        }

        public virtual void OnKeyUp(HUDKeyUpEventArgs e)
        {
        }

        public virtual void OnKeyPressed(HUDKeyPressedEventArgs e)
        {
        }

        #endregion

        #endregion
    }
}
